{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "c4387eeab213fd5f",
   "metadata": {},
   "source": [
    "### Building a Regression Model with ChemProp\n",
    "\n",
    "This notebook shows how to build a ChemProp model.  The notebook borrows heavily from the ChemProp examples. \n",
    "1. Read the input data\n",
    "2. Divide the dataset into training, validation, and test sets\n",
    "3. Create the datasets\n",
    "4. Create dataloaders\n",
    "5. Create the model\n",
    "6. Train the model\n",
    "7. Predict the values for the test set\n",
    "8. Evaluate the model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "d1433b9d3ff861e7",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-07-30T17:55:27.590384Z",
     "start_time": "2024-07-30T17:55:25.076717Z"
    }
   },
   "outputs": [],
   "source": [
    "import itertools\n",
    "\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "import seaborn as sns\n",
    "from chemprop import data, featurizers, nn, models\n",
    "from lightning import pytorch as pl\n",
    "from sklearn.metrics import r2_score, root_mean_squared_error\n",
    "from sklearn.model_selection import train_test_split"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ea5a0149-5a99-457d-a7b1-8e6d4d478238",
   "metadata": {},
   "source": [
    "### 1. Read the input data\n",
    "Read the input data. For this exercise, we'll use one of the datasets from [this paper by Fang et al](https://pubs.acs.org/doi/10.1021/acs.jcim.3c00160). "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "3f4772a9-6a1f-4278-bf43-e9bdb14e4b87",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-07-30T17:55:27.600527Z",
     "start_time": "2024-07-30T17:55:27.591469Z"
    }
   },
   "outputs": [],
   "source": [
    "df = pd.read_csv(\"https://raw.githubusercontent.com/PatWalters/practical_cheminformatics_tutorials/main/chemprop/data/biogen_logS.csv\")\n",
    "y_col = \"logS\""
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7b8c2245-bf8d-465f-aad6-5168f8e86a94",
   "metadata": {},
   "source": [
    "### 2. Divide the dataset into training, validation, and test sets.\n",
    "Divide the dataset into training, validation, and test sets."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "49fe4b88f5b40163",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-07-30T17:55:27.609542Z",
     "start_time": "2024-07-30T17:55:27.601188Z"
    }
   },
   "outputs": [],
   "source": [
    "train_frac, val_frac, test_frac = 0.8, 0.1, 0.1\n",
    "train, test = train_test_split(df, test_size=test_frac)\n",
    "train, val = train_test_split(train, test_size=len(test))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d04c0c0f-1469-4399-a38d-7df53262fefd",
   "metadata": {},
   "source": [
    "Examine the sizes of the training, validation, and test sets."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "7170d683-d9d1-4d21-9d19-9da0dafb18d2",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-07-30T17:55:27.614922Z",
     "start_time": "2024-07-30T17:55:27.611247Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(1737, 218, 218)"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "len(train), len(val), len(test)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "355c9929-03cf-4e99-bcbd-ade52ba8df29",
   "metadata": {},
   "source": [
    "### 3. Create the datasets\n",
    "Convert the data to MoleculeDatapoints"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "initial_id",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-07-30T17:55:27.769291Z",
     "start_time": "2024-07-30T17:55:27.615655Z"
    }
   },
   "outputs": [],
   "source": [
    "train_pt = [data.MoleculeDatapoint.from_smi(smi, [y]) for smi, y in train[[\"SMILES\", y_col]].values]\n",
    "val_pt = [data.MoleculeDatapoint.from_smi(smi, [y]) for smi, y in val[[\"SMILES\", y_col]].values]\n",
    "test_pt = [data.MoleculeDatapoint.from_smi(smi, [y]) for smi, y in test[[\"SMILES\", y_col]].values]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "02531c9b-20a2-4cb2-9f11-615f2e3359c6",
   "metadata": {},
   "source": [
    "Create a featurizer to generate graph node and edge features for the molecules."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "f10597d22823a4d8",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-07-30T17:55:27.771700Z",
     "start_time": "2024-07-30T17:55:27.770090Z"
    }
   },
   "outputs": [],
   "source": [
    "featurizer = featurizers.SimpleMoleculeMolGraphFeaturizer()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f6038f4f-245a-4a7f-9e42-535adde00256",
   "metadata": {},
   "source": [
    "Create a training dataset by featurizing the training set, then scale the training set. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "51a767f3-2036-4029-9a66-ff0f2f5e1f06",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-07-30T17:55:27.775139Z",
     "start_time": "2024-07-30T17:55:27.772374Z"
    }
   },
   "outputs": [],
   "source": [
    "train_dset = data.MoleculeDataset(train_pt, featurizer)\n",
    "scaler = train_dset.normalize_targets()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6d69c66a-80e0-40c9-b80a-5798a77ce105",
   "metadata": {},
   "source": [
    "Do the same with the validation dataset.  Use the scaler we created for the training set to scale the validation set. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "5656fc28-72ea-466f-8215-2271be5106a7",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-07-30T17:55:27.779292Z",
     "start_time": "2024-07-30T17:55:27.775912Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<style>#sk-container-id-1 {\n",
       "  /* Definition of color scheme common for light and dark mode */\n",
       "  --sklearn-color-text: black;\n",
       "  --sklearn-color-line: gray;\n",
       "  /* Definition of color scheme for unfitted estimators */\n",
       "  --sklearn-color-unfitted-level-0: #fff5e6;\n",
       "  --sklearn-color-unfitted-level-1: #f6e4d2;\n",
       "  --sklearn-color-unfitted-level-2: #ffe0b3;\n",
       "  --sklearn-color-unfitted-level-3: chocolate;\n",
       "  /* Definition of color scheme for fitted estimators */\n",
       "  --sklearn-color-fitted-level-0: #f0f8ff;\n",
       "  --sklearn-color-fitted-level-1: #d4ebff;\n",
       "  --sklearn-color-fitted-level-2: #b3dbfd;\n",
       "  --sklearn-color-fitted-level-3: cornflowerblue;\n",
       "\n",
       "  /* Specific color for light theme */\n",
       "  --sklearn-color-text-on-default-background: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, black)));\n",
       "  --sklearn-color-background: var(--sg-background-color, var(--theme-background, var(--jp-layout-color0, white)));\n",
       "  --sklearn-color-border-box: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, black)));\n",
       "  --sklearn-color-icon: #696969;\n",
       "\n",
       "  @media (prefers-color-scheme: dark) {\n",
       "    /* Redefinition of color scheme for dark theme */\n",
       "    --sklearn-color-text-on-default-background: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, white)));\n",
       "    --sklearn-color-background: var(--sg-background-color, var(--theme-background, var(--jp-layout-color0, #111)));\n",
       "    --sklearn-color-border-box: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, white)));\n",
       "    --sklearn-color-icon: #878787;\n",
       "  }\n",
       "}\n",
       "\n",
       "#sk-container-id-1 {\n",
       "  color: var(--sklearn-color-text);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 pre {\n",
       "  padding: 0;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 input.sk-hidden--visually {\n",
       "  border: 0;\n",
       "  clip: rect(1px 1px 1px 1px);\n",
       "  clip: rect(1px, 1px, 1px, 1px);\n",
       "  height: 1px;\n",
       "  margin: -1px;\n",
       "  overflow: hidden;\n",
       "  padding: 0;\n",
       "  position: absolute;\n",
       "  width: 1px;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-dashed-wrapped {\n",
       "  border: 1px dashed var(--sklearn-color-line);\n",
       "  margin: 0 0.4em 0.5em 0.4em;\n",
       "  box-sizing: border-box;\n",
       "  padding-bottom: 0.4em;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-container {\n",
       "  /* jupyter's `normalize.less` sets `[hidden] { display: none; }`\n",
       "     but bootstrap.min.css set `[hidden] { display: none !important; }`\n",
       "     so we also need the `!important` here to be able to override the\n",
       "     default hidden behavior on the sphinx rendered scikit-learn.org.\n",
       "     See: https://github.com/scikit-learn/scikit-learn/issues/21755 */\n",
       "  display: inline-block !important;\n",
       "  position: relative;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-text-repr-fallback {\n",
       "  display: none;\n",
       "}\n",
       "\n",
       "div.sk-parallel-item,\n",
       "div.sk-serial,\n",
       "div.sk-item {\n",
       "  /* draw centered vertical line to link estimators */\n",
       "  background-image: linear-gradient(var(--sklearn-color-text-on-default-background), var(--sklearn-color-text-on-default-background));\n",
       "  background-size: 2px 100%;\n",
       "  background-repeat: no-repeat;\n",
       "  background-position: center center;\n",
       "}\n",
       "\n",
       "/* Parallel-specific style estimator block */\n",
       "\n",
       "#sk-container-id-1 div.sk-parallel-item::after {\n",
       "  content: \"\";\n",
       "  width: 100%;\n",
       "  border-bottom: 2px solid var(--sklearn-color-text-on-default-background);\n",
       "  flex-grow: 1;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-parallel {\n",
       "  display: flex;\n",
       "  align-items: stretch;\n",
       "  justify-content: center;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  position: relative;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-parallel-item {\n",
       "  display: flex;\n",
       "  flex-direction: column;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-parallel-item:first-child::after {\n",
       "  align-self: flex-end;\n",
       "  width: 50%;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-parallel-item:last-child::after {\n",
       "  align-self: flex-start;\n",
       "  width: 50%;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-parallel-item:only-child::after {\n",
       "  width: 0;\n",
       "}\n",
       "\n",
       "/* Serial-specific style estimator block */\n",
       "\n",
       "#sk-container-id-1 div.sk-serial {\n",
       "  display: flex;\n",
       "  flex-direction: column;\n",
       "  align-items: center;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  padding-right: 1em;\n",
       "  padding-left: 1em;\n",
       "}\n",
       "\n",
       "\n",
       "/* Toggleable style: style used for estimator/Pipeline/ColumnTransformer box that is\n",
       "clickable and can be expanded/collapsed.\n",
       "- Pipeline and ColumnTransformer use this feature and define the default style\n",
       "- Estimators will overwrite some part of the style using the `sk-estimator` class\n",
       "*/\n",
       "\n",
       "/* Pipeline and ColumnTransformer style (default) */\n",
       "\n",
       "#sk-container-id-1 div.sk-toggleable {\n",
       "  /* Default theme specific background. It is overwritten whether we have a\n",
       "  specific estimator or a Pipeline/ColumnTransformer */\n",
       "  background-color: var(--sklearn-color-background);\n",
       "}\n",
       "\n",
       "/* Toggleable label */\n",
       "#sk-container-id-1 label.sk-toggleable__label {\n",
       "  cursor: pointer;\n",
       "  display: block;\n",
       "  width: 100%;\n",
       "  margin-bottom: 0;\n",
       "  padding: 0.5em;\n",
       "  box-sizing: border-box;\n",
       "  text-align: center;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 label.sk-toggleable__label-arrow:before {\n",
       "  /* Arrow on the left of the label */\n",
       "  content: \"▸\";\n",
       "  float: left;\n",
       "  margin-right: 0.25em;\n",
       "  color: var(--sklearn-color-icon);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 label.sk-toggleable__label-arrow:hover:before {\n",
       "  color: var(--sklearn-color-text);\n",
       "}\n",
       "\n",
       "/* Toggleable content - dropdown */\n",
       "\n",
       "#sk-container-id-1 div.sk-toggleable__content {\n",
       "  max-height: 0;\n",
       "  max-width: 0;\n",
       "  overflow: hidden;\n",
       "  text-align: left;\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-toggleable__content.fitted {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-toggleable__content pre {\n",
       "  margin: 0.2em;\n",
       "  border-radius: 0.25em;\n",
       "  color: var(--sklearn-color-text);\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-toggleable__content.fitted pre {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 input.sk-toggleable__control:checked~div.sk-toggleable__content {\n",
       "  /* Expand drop-down */\n",
       "  max-height: 200px;\n",
       "  max-width: 100%;\n",
       "  overflow: auto;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 input.sk-toggleable__control:checked~label.sk-toggleable__label-arrow:before {\n",
       "  content: \"▾\";\n",
       "}\n",
       "\n",
       "/* Pipeline/ColumnTransformer-specific style */\n",
       "\n",
       "#sk-container-id-1 div.sk-label input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  color: var(--sklearn-color-text);\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-label.fitted input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "/* Estimator-specific style */\n",
       "\n",
       "/* Colorize estimator box */\n",
       "#sk-container-id-1 div.sk-estimator input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-estimator.fitted input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-label label.sk-toggleable__label,\n",
       "#sk-container-id-1 div.sk-label label {\n",
       "  /* The background is the default theme color */\n",
       "  color: var(--sklearn-color-text-on-default-background);\n",
       "}\n",
       "\n",
       "/* On hover, darken the color of the background */\n",
       "#sk-container-id-1 div.sk-label:hover label.sk-toggleable__label {\n",
       "  color: var(--sklearn-color-text);\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "/* Label box, darken color on hover, fitted */\n",
       "#sk-container-id-1 div.sk-label.fitted:hover label.sk-toggleable__label.fitted {\n",
       "  color: var(--sklearn-color-text);\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "/* Estimator label */\n",
       "\n",
       "#sk-container-id-1 div.sk-label label {\n",
       "  font-family: monospace;\n",
       "  font-weight: bold;\n",
       "  display: inline-block;\n",
       "  line-height: 1.2em;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-label-container {\n",
       "  text-align: center;\n",
       "}\n",
       "\n",
       "/* Estimator-specific */\n",
       "#sk-container-id-1 div.sk-estimator {\n",
       "  font-family: monospace;\n",
       "  border: 1px dotted var(--sklearn-color-border-box);\n",
       "  border-radius: 0.25em;\n",
       "  box-sizing: border-box;\n",
       "  margin-bottom: 0.5em;\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-estimator.fitted {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-0);\n",
       "}\n",
       "\n",
       "/* on hover */\n",
       "#sk-container-id-1 div.sk-estimator:hover {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-estimator.fitted:hover {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "/* Specification for estimator info (e.g. \"i\" and \"?\") */\n",
       "\n",
       "/* Common style for \"i\" and \"?\" */\n",
       "\n",
       ".sk-estimator-doc-link,\n",
       "a:link.sk-estimator-doc-link,\n",
       "a:visited.sk-estimator-doc-link {\n",
       "  float: right;\n",
       "  font-size: smaller;\n",
       "  line-height: 1em;\n",
       "  font-family: monospace;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  border-radius: 1em;\n",
       "  height: 1em;\n",
       "  width: 1em;\n",
       "  text-decoration: none !important;\n",
       "  margin-left: 1ex;\n",
       "  /* unfitted */\n",
       "  border: var(--sklearn-color-unfitted-level-1) 1pt solid;\n",
       "  color: var(--sklearn-color-unfitted-level-1);\n",
       "}\n",
       "\n",
       ".sk-estimator-doc-link.fitted,\n",
       "a:link.sk-estimator-doc-link.fitted,\n",
       "a:visited.sk-estimator-doc-link.fitted {\n",
       "  /* fitted */\n",
       "  border: var(--sklearn-color-fitted-level-1) 1pt solid;\n",
       "  color: var(--sklearn-color-fitted-level-1);\n",
       "}\n",
       "\n",
       "/* On hover */\n",
       "div.sk-estimator:hover .sk-estimator-doc-link:hover,\n",
       ".sk-estimator-doc-link:hover,\n",
       "div.sk-label-container:hover .sk-estimator-doc-link:hover,\n",
       ".sk-estimator-doc-link:hover {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-3);\n",
       "  color: var(--sklearn-color-background);\n",
       "  text-decoration: none;\n",
       "}\n",
       "\n",
       "div.sk-estimator.fitted:hover .sk-estimator-doc-link.fitted:hover,\n",
       ".sk-estimator-doc-link.fitted:hover,\n",
       "div.sk-label-container:hover .sk-estimator-doc-link.fitted:hover,\n",
       ".sk-estimator-doc-link.fitted:hover {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-3);\n",
       "  color: var(--sklearn-color-background);\n",
       "  text-decoration: none;\n",
       "}\n",
       "\n",
       "/* Span, style for the box shown on hovering the info icon */\n",
       ".sk-estimator-doc-link span {\n",
       "  display: none;\n",
       "  z-index: 9999;\n",
       "  position: relative;\n",
       "  font-weight: normal;\n",
       "  right: .2ex;\n",
       "  padding: .5ex;\n",
       "  margin: .5ex;\n",
       "  width: min-content;\n",
       "  min-width: 20ex;\n",
       "  max-width: 50ex;\n",
       "  color: var(--sklearn-color-text);\n",
       "  box-shadow: 2pt 2pt 4pt #999;\n",
       "  /* unfitted */\n",
       "  background: var(--sklearn-color-unfitted-level-0);\n",
       "  border: .5pt solid var(--sklearn-color-unfitted-level-3);\n",
       "}\n",
       "\n",
       ".sk-estimator-doc-link.fitted span {\n",
       "  /* fitted */\n",
       "  background: var(--sklearn-color-fitted-level-0);\n",
       "  border: var(--sklearn-color-fitted-level-3);\n",
       "}\n",
       "\n",
       ".sk-estimator-doc-link:hover span {\n",
       "  display: block;\n",
       "}\n",
       "\n",
       "/* \"?\"-specific style due to the `<a>` HTML tag */\n",
       "\n",
       "#sk-container-id-1 a.estimator_doc_link {\n",
       "  float: right;\n",
       "  font-size: 1rem;\n",
       "  line-height: 1em;\n",
       "  font-family: monospace;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  border-radius: 1rem;\n",
       "  height: 1rem;\n",
       "  width: 1rem;\n",
       "  text-decoration: none;\n",
       "  /* unfitted */\n",
       "  color: var(--sklearn-color-unfitted-level-1);\n",
       "  border: var(--sklearn-color-unfitted-level-1) 1pt solid;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 a.estimator_doc_link.fitted {\n",
       "  /* fitted */\n",
       "  border: var(--sklearn-color-fitted-level-1) 1pt solid;\n",
       "  color: var(--sklearn-color-fitted-level-1);\n",
       "}\n",
       "\n",
       "/* On hover */\n",
       "#sk-container-id-1 a.estimator_doc_link:hover {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-3);\n",
       "  color: var(--sklearn-color-background);\n",
       "  text-decoration: none;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 a.estimator_doc_link.fitted:hover {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-3);\n",
       "}\n",
       "</style><div id=\"sk-container-id-1\" class=\"sk-top-container\"><div class=\"sk-text-repr-fallback\"><pre>StandardScaler()</pre><b>In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook. <br />On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.</b></div><div class=\"sk-container\" hidden><div class=\"sk-item\"><div class=\"sk-estimator fitted sk-toggleable\"><input class=\"sk-toggleable__control sk-hidden--visually\" id=\"sk-estimator-id-1\" type=\"checkbox\" checked><label for=\"sk-estimator-id-1\" class=\"sk-toggleable__label fitted sk-toggleable__label-arrow fitted\">&nbsp;&nbsp;StandardScaler<a class=\"sk-estimator-doc-link fitted\" rel=\"noreferrer\" target=\"_blank\" href=\"https://scikit-learn.org/1.4/modules/generated/sklearn.preprocessing.StandardScaler.html\">?<span>Documentation for StandardScaler</span></a><span class=\"sk-estimator-doc-link fitted\">i<span>Fitted</span></span></label><div class=\"sk-toggleable__content fitted\"><pre>StandardScaler()</pre></div> </div></div></div></div>"
      ],
      "text/plain": [
       "StandardScaler()"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "val_dset = data.MoleculeDataset(val_pt, featurizer)\n",
    "val_dset.normalize_targets(scaler)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "55f29e5f-00d9-4b75-9472-74a2b0971823",
   "metadata": {},
   "source": [
    "Create the test dataset and generate a scaler. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "1689fb59-30b8-485d-925e-20d9a61d687f",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-07-30T17:55:27.803917Z",
     "start_time": "2024-07-30T17:55:27.779912Z"
    }
   },
   "outputs": [],
   "source": [
    "test_dset = data.MoleculeDataset(test_pt, featurizer)\n",
    "output_transform = nn.UnscaleTransform.from_standard_scaler(scaler)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f9a591c7-ec12-42ba-9449-77fe4e433f5a",
   "metadata": {},
   "source": [
    "### 4. Create the dataloaders\n",
    "Create dataloaders for the training validation and test sets.  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "22fb820e-478c-4294-90fe-85d91afd2710",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-07-30T17:55:27.808243Z",
     "start_time": "2024-07-30T17:55:27.806262Z"
    }
   },
   "outputs": [],
   "source": [
    "num_workers = 0\n",
    "train_loader = data.build_dataloader(train_dset, num_workers=num_workers)\n",
    "val_loader = data.build_dataloader(val_dset, num_workers=num_workers, shuffle=False)\n",
    "test_loader = data.build_dataloader(test_dset, num_workers=num_workers, shuffle=False)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "80b3f796-28c5-4282-a08f-ff3569f56cf6",
   "metadata": {},
   "source": [
    "### 5. Create the model\n",
    "Create the Feed Forward Neural Network (FFNN)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "582d0a76-1c0c-4ed7-b79d-1eaf5d1044e6",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-07-30T17:55:27.816232Z",
     "start_time": "2024-07-30T17:55:27.809127Z"
    }
   },
   "outputs": [],
   "source": [
    "mp = nn.BondMessagePassing()\n",
    "agg = nn.MeanAggregation()\n",
    "ffn_input_dim = mp.output_dim\n",
    "ffn = nn.RegressionFFN(input_dim=ffn_input_dim, output_transform=output_transform)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ec46f74c-17b6-4117-9043-5a0cf03bcb3b",
   "metadata": {},
   "source": [
    "Create the Message Passing Neural Network (MPNN)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "9187e7ae-a1db-4e54-afcb-7002d50d2761",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-07-30T17:55:27.822778Z",
     "start_time": "2024-07-30T17:55:27.816973Z"
    }
   },
   "outputs": [],
   "source": [
    "batch_norm = True\n",
    "metric_list = [nn.metrics.RMSEMetric()]\n",
    "mpnn = models.MPNN(mp, agg, ffn, batch_norm, metric_list)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3de6f4cc-0e70-4f84-af8c-511c8f2d4f60",
   "metadata": {},
   "source": [
    "### 6. Train the model\n",
    "Train the MPNN on the training and validation sets"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "6b6b056c-cc56-4b4d-ae34-40de7df20f65",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-07-30T17:56:07.486708Z",
     "start_time": "2024-07-30T17:55:27.823569Z"
    }
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "GPU available: True (mps), used: False\n",
      "TPU available: False, using: 0 TPU cores\n",
      "IPU available: False, using: 0 IPUs\n",
      "HPU available: False, using: 0 HPUs\n",
      "/Users/pwalters/miniconda3/envs/chemprop/lib/python3.11/site-packages/lightning/pytorch/trainer/setup.py:187: GPU available but not used. You can set it by doing `Trainer(accelerator='gpu')`.\n",
      "Loading `train_dataloader` to estimate number of stepping batches.\n",
      "/Users/pwalters/miniconda3/envs/chemprop/lib/python3.11/site-packages/lightning/pytorch/trainer/connectors/data_connector.py:441: The 'train_dataloader' does not have many workers which may be a bottleneck. Consider increasing the value of the `num_workers` argument` to `num_workers=9` in the `DataLoader` to improve performance.\n",
      "\n",
      "  | Name            | Type               | Params\n",
      "-------------------------------------------------------\n",
      "0 | message_passing | BondMessagePassing | 227 K \n",
      "1 | agg             | MeanAggregation    | 0     \n",
      "2 | bn              | BatchNorm1d        | 600   \n",
      "3 | predictor       | RegressionFFN      | 90.6 K\n",
      "4 | X_d_transform   | Identity           | 0     \n",
      "-------------------------------------------------------\n",
      "318 K     Trainable params\n",
      "0         Non-trainable params\n",
      "318 K     Total params\n",
      "1.276     Total estimated model params size (MB)\n"
     ]
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Sanity Checking: |                                                                                            …"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/Users/pwalters/miniconda3/envs/chemprop/lib/python3.11/site-packages/lightning/pytorch/trainer/connectors/data_connector.py:441: The 'val_dataloader' does not have many workers which may be a bottleneck. Consider increasing the value of the `num_workers` argument` to `num_workers=9` in the `DataLoader` to improve performance.\n"
     ]
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "9ec1979444274b34b31b863fadec5013",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Training: |                                                                                                   …"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Validation: |                                                                                                 …"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Validation: |                                                                                                 …"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Validation: |                                                                                                 …"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Validation: |                                                                                                 …"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Validation: |                                                                                                 …"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Validation: |                                                                                                 …"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Validation: |                                                                                                 …"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Validation: |                                                                                                 …"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Validation: |                                                                                                 …"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Validation: |                                                                                                 …"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Validation: |                                                                                                 …"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Validation: |                                                                                                 …"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Validation: |                                                                                                 …"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Validation: |                                                                                                 …"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Validation: |                                                                                                 …"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Validation: |                                                                                                 …"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Validation: |                                                                                                 …"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Validation: |                                                                                                 …"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Validation: |                                                                                                 …"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Validation: |                                                                                                 …"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "`Trainer.fit` stopped: `max_epochs=20` reached.\n"
     ]
    }
   ],
   "source": [
    "trainer = pl.Trainer(\n",
    "    logger=False,\n",
    "    enable_checkpointing=False,\n",
    "    enable_progress_bar=True,\n",
    "    accelerator=\"cpu\",\n",
    "    devices=1,\n",
    "    max_epochs=20,  # number of epochs to train for\n",
    ")\n",
    "trainer.fit(mpnn, train_loader, val_loader)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "87660b3d-8b58-4d15-8fe1-ca09f5173eb4",
   "metadata": {},
   "source": [
    "### 7. Predict the values for the test set\n",
    "Predict the values for the test set. ChemProp returns the results from **predict** as an array of PyTorch tensors, which isn't particularly convenient. We'll fix that below. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "99a5db4c700be4de",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-07-30T17:56:07.663770Z",
     "start_time": "2024-07-30T17:56:07.488138Z"
    }
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/Users/pwalters/miniconda3/envs/chemprop/lib/python3.11/site-packages/lightning/pytorch/trainer/connectors/data_connector.py:441: The 'predict_dataloader' does not have many workers which may be a bottleneck. Consider increasing the value of the `num_workers` argument` to `num_workers=9` in the `DataLoader` to improve performance.\n"
     ]
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "537c33385e7b4cdd99bd35f792a9712c",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Predicting: |                                                                                                 …"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "pred_tensor = trainer.predict(mpnn, test_loader)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "8f5e663b-2ec3-4cf7-8ad2-39771bfe0242",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-07-30T17:56:07.668778Z",
     "start_time": "2024-07-30T17:56:07.664803Z"
    }
   },
   "outputs": [],
   "source": [
    "pred = np.array(list(itertools.chain(*pred_tensor))).flatten()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "8aaf6296-37f2-4ad3-8068-e859842982f9",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-07-30T17:56:07.673176Z",
     "start_time": "2024-07-30T17:56:07.669743Z"
    }
   },
   "outputs": [],
   "source": [
    "pred_df = pd.DataFrame({y_col: test[y_col], 'pred': pred})"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3f5de4b0-eff6-42ad-a806-900a7494680b",
   "metadata": {},
   "source": [
    "### 8. Evaluate the model\n",
    "Plot the experimental vs predicted values."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "a8ec6416-e759-44f0-9394-43d803c6b817",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-07-30T17:56:07.957623Z",
     "start_time": "2024-07-30T17:56:07.674173Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<seaborn.axisgrid.FacetGrid at 0x17300cbd0>"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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OLKxu/3227Fnzx688cYbuR7KsChQj9E3vvENXHfddcM+pra2dlzfu6qqCgDQ2tqK6urqxPXW1lacccYZ4/qe6TDa91xVVTUoyUjTNHR1dSXe22gsXboUAFBfX2+ZQF1WVgZBENDa2pp0vbW1dcj3VlVVNabHW8143vNAkiThzDPPRH19fSaGmHND/Yy9Xu+knE0PZcmSJZYPdgN99atfTSS8jrTak+t/y7RHPUbl5eWYN2/esL9sNtu4vvesWbNQVVWF1157LXEtEAhg+/btSbOUbBvte162bBl6enqwc+fOxHNff/11GIaRCL6j8d577wFA0s1KrtlsNixevDjpZ2MYBl577bUhfzbLli1LejwAbNy4Mac/y7EYz3seSNd17N6921I/y3TK959xurz33nt58zNmjOGrX/0qnnnmGbz++uuYNWvWiM/J+c85KylrBero0aNs165d7J577mFut5vt2rWL7dq1i/X29iYeM3fuXPb0008nfv9f//VfrKioiD333HPsgw8+YJdddhmbNWsWi0QiuXgLY/bJT36SnXnmmWz79u3sjTfeYKeccgq76qqrEl8/duwYmzt3Ltu+fTtjjLH6+nr2/e9/n73zzjvs8OHD7LnnnmO1tbVsxYoVuXoLQ/rDH/7AZFlmjz/+ONu3bx+7+eabWVFREWtpaWGMMfalL32J3XXXXYnHv/nmm0wURfbTn/6U7d+/n33ve99jkiSx3bt35+otjNlY3/M999zDXn75ZdbQ0MB27tzJvvCFLzC73c727t2bq7cwJr29vYl/pwDYfffdx3bt2sWOHj3KGGPsrrvuYl/60pcSjz906BBzOp3s3/7t39j+/fvZr3/9ayYIAnvppZdy9RbGbKzv+ec//zl79tln2UcffcR2797Nvva1rzGe59mrr76aq7cwJrfddhvz+Xxs06ZNrLm5OfErHA4nHmO1f8sUqDNozZo1DMCgX3//+98TjwHAHnvsscTvDcNg3/nOd1hlZSWTZZl9/OMfZwcOHMj+4Meps7OTXXXVVcztdjOv18uuv/76pBuTw4cPJ/0ZNDY2shUrVrCSkhImyzKbPXs2+7d/+zfm9/tz9A6G96tf/YpNnz6d2Ww2tmTJEvbWW28lvrZy5Uq2Zs2apMf/8Y9/ZHPmzGE2m40tWLCAvfDCC1ke8cSN5T3feeedicdWVlayT33qU+zdd9/NwajHJ370aOCv+Htcs2YNW7ly5aDnnHHGGcxms7Ha2tqkf8/5YKzv+Uc/+hGrq6tjdrudlZSUsFWrVrHXX389N4Mfh1TvdeDnsNX+LVObS0IIIcTCaI+aEEIIsTAK1IQQQoiFUaAmhBBCLIwCNSGEEGJhFKgJIYQQC6NATQghhFgYBWpCCCHEwihQE0IIIRZGgZoQktKqVatw55135noYhBQ8CtSEkKzQdR3/9V//hXnz5sHhcKCkpARLly7FI488kuuhEWJp1OaSEJIV99xzDx588EH8z//8D84++2wEAgG888476O7uzvXQCLE0mlETQkbU3d2Na6+9FsXFxXA6nbj44ovx0UcfJT3m4YcfRk1NDZxOJ6644grcd999KCoqSnz9L3/5C77yla/gc5/7HGbNmoVFixbhhhtuwDe/+c0svxtC8gsFakLIiK677jq88847+Mtf/oJt27aBMYZPfepTUFUVAPDmm2/i1ltvxde+9jW89957uOiii/Cf//mfSd+jqqoKr7/+Otrb23PxFgjJW9Q9ixCS0qpVq3DGGWfg9ttvx5w5c/Dmm29i+fLlAIDOzk7U1NTgiSeewOc+9zl84QtfQDAYxPPPP594/he/+EU8//zz6OnpAQDs27cPn/3sZ3HgwAEsWLAAy5cvx2WXXYaLL744F2+PkLxBM2pCyLD2798PURSxdOnSxLXS0lLMnTsX+/fvBwAcOHAAS5YsSXrewN+feuqp2LNnD9566y18+ctfRltbGy699FLceOONmX8ThOQxCtSEkKzheR7nnHMO7rzzTjz99NN4/PHH8Zvf/AaHDx/O9dAIsSwK1ISQYc2fPx+apmH79u2Ja52dnThw4ABOPfVUAMDcuXPx9ttvJz1v4O9TiT8/FAqlccSETC50PIsQMqxTTjkFl112GW666SY8+OCD8Hg8uOuuuzB16lRcdtllAIA77rgDK1aswH333YdLL70Ur7/+Ov72t7+B47jE9/nsZz+L8847D8uXL0dVVRUOHz6MdevWYc6cOZg3b16u3h4hlkczakLIiB577DEsXrwY//zP/4xly5aBMYYXX3wRkiQBAM477zw88MADuO+++7Bo0SK89NJL+PrXvw673Z74HqtXr8Zf//pXXHrppZgzZw7WrFmDefPm4ZVXXoEo0pyBkKFQ1jchJCNuuukmfPjhh/jHP/6R66EQktfoNpYQkhY//elPcdFFF8HlcuFvf/sbnnjiCdx///25HhYheY9m1ISQtPj85z+PTZs2obe3F7W1tbjjjjtw66235npYhOQ9CtSEEEKIhVEyGSGEEGJhFKgJIYQQC6NATQghhFgYBWpCCCHEwihQE0IIIRZGgZoQQgixMArUhBBCiIVRoCaEEEIs7P8HNlIQKJhwJykAAAAASUVORK5CYII=",
      "text/plain": [
       "<Figure size 500x500 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "sns.lmplot(x=y_col, y=\"pred\", data=pred_df)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "02eba13c-d357-48bb-8728-71889d4b6432",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-07-30T17:56:07.968832Z",
     "start_time": "2024-07-30T17:56:07.961129Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.468182247508493"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "r2_score(pred_df[y_col], pred)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "e2587ebb-b695-47a7-b8ea-db4a2e6b69f4",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-07-30T17:56:07.979775Z",
     "start_time": "2024-07-30T17:56:07.972450Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.5014797857964977"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "root_mean_squared_error(pred_df[y_col], pred)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "3d0a72aa-9e4c-4e54-abc4-074e7b72dc8d",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-07-30T17:56:07.982019Z",
     "start_time": "2024-07-30T17:56:07.980660Z"
    }
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.9"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
